import { CreateDependencies, logger, hashArray } from '@nx/devkit';
import { readMavenCache, getCachePath } from './maven-data-cache';
import { calculateHashesForCreateNodes } from '@nx/devkit/src/utils/calculate-hash-for-create-nodes';
import { createProjectRootMappingsFromProjectConfigurations } from '@nx/devkit/internal';
import { DEFAULT_OPTIONS, MavenPluginOptions } from './types';
import { globWithWorkspaceContext } from 'nx/src/utils/workspace-context';
import { dirname } from 'path';
import { hashObject } from 'nx/src/devkit-internals';

/**
 * Create dependencies between Maven projects by analyzing the createNodesResults
 * Uses cached Maven analysis data that was generated by createNodesV2
 */
export const createDependencies: CreateDependencies = async (
  options,
  context
) => {
  const opts: MavenPluginOptions = {
    ...DEFAULT_OPTIONS,
    ...(options as MavenPluginOptions),
  };

  // Get cache path based on options
  const optionsHash = hashObject(opts);
  const cachePath = getCachePath(context.workspaceRoot, optionsHash);
  const mavenCache = readMavenCache(cachePath);

  // Find all pom.xml files (same as createNodesV2)
  const configFiles = await globWithWorkspaceContext(context.workspaceRoot, [
    '**/pom.xml',
  ]);

  // Calculate the same hash as createNodesV2
  const projectRoots = configFiles.map((file) => dirname(file));
  const hashes = await calculateHashesForCreateNodes(
    projectRoots,
    opts,
    context
  );
  const hash = hashArray(hashes);

  // Get cached Maven analysis data that was generated by createNodesV2
  const mavenData = mavenCache[hash];
  if (!mavenData) {
    logger.verbose(
      '[Maven Dependencies] No Maven data found in workspace:',
      context.workspaceRoot
    );
    return [];
  }

  logger.verbose(
    '[Maven Dependencies] Found Maven data with',
    mavenData.createDependenciesResults.length,
    'dependencies'
  );

  // Create a mapping from project root to project name
  const rootToProjectMap = createProjectRootMappingsFromProjectConfigurations(
    context.projects
  );

  // Extract and transform dependencies from the mavenData
  const transformedDependencies = mavenData.createDependenciesResults.map(
    (dep) => ({
      ...dep,
      source: rootToProjectMap.get(dep.source),
      target: rootToProjectMap.get(dep.target),
    })
  );

  return transformedDependencies;
};
